package com.demo.wrapper.interfaces;

import com.demo.wrapper.enums.QueryEnum;
import com.demo.wrapper.pojo.Arg;
import com.demo.wrapper.enums.OrderEnum;

import java.util.Objects;
import java.util.function.Consumer;

/**
 * 全局限制
 * 只对调用.searchSourceBuilder()方法的wrapper有效，该wrapper的子wrapper的全局限制无效
 *
 * @param <Wrapper>    条件拼接类，需继承Limit接口
 * @param <AggWrapper> 聚合拼接类，需继承Agg接口
 * @author arthur_zhou
 */
public interface IEsLimitWrapper<Wrapper extends IEsLimitWrapper<Wrapper, AggWrapper>, AggWrapper extends IEsAggWrapper<AggWrapper, Wrapper>>
        extends IBaseWrapper<Wrapper> {

    /**
     * 限制返回
     *
     * @param from 起始下标
     * @return this
     */
    default Wrapper from(int from) {
        return addLimit(new Arg(QueryEnum.FROM, from));
    }

    /**
     * 限制返回
     *
     * @param size 返回条数
     * @return
     */
    default Wrapper size(int size) {
        return addLimit(new Arg(QueryEnum.SIZE, size));
    }

    /**
     * 限制返回
     *
     * @param from 起始下标
     * @param size 返回条数
     * @return
     */
    default Wrapper limit(int from, int size) {
        return addLimit(new Arg(QueryEnum.LIMIT, null, null, null, from, size));
    }

    /**
     * 展示字段
     *
     * @param column  字段
     * @param columns 更多字段
     * @return
     */
    default Wrapper select(String column, String... columns) {
        return addLimit(new Arg(QueryEnum.INCLUDES, null, null, null, column, columns));
    }

    /**
     * 不展示字段
     *
     * @param column  字段
     * @param columns 更多字段
     * @return
     */
    default Wrapper notSelect(String column, String... columns) {
        return addLimit(new Arg(QueryEnum.EXCLUDES, null, null, null, column, columns));
    }

    /**
     * 限制展示
     *
     * @param includes
     * @param excludes
     * @return
     */
    default Wrapper fetchSource(String[] includes, String[] excludes) {
        return addLimit(new Arg(QueryEnum.FETCH_SOURCE, null, null, null, includes, excludes));
    }

    /**
     * 聚合
     *
     * @param consumer 函数 v->v.terms().sum().agg().agg() 只有sum()有效，子聚合多次有效
     * @return
     */
    Wrapper agg(Consumer<AggWrapper> consumer);


    /**
     * 管道聚合 最大值
     *
     * @param name
     * @param path
     * @return
     */
    default Wrapper maxBucket(String name, String path) {
        // todo
        return null;
    }

    /**
     * 倒序
     *
     * @param column
     * @param columns
     * @return
     */
    default Wrapper orderByDesc(String column, String... columns) {
        Wrapper wrapper = sort(column, OrderEnum.DESC);
        if (Objects.nonNull(column) && columns.length > 0) {
            for (String field : columns) {
                wrapper = sort(field, OrderEnum.DESC);
            }
        }
        return wrapper;
    }

    /**
     * 顺序
     *
     * @param column
     * @param columns
     * @return
     */
    default Wrapper orderByAsc(String column, String... columns) {
        Wrapper wrapper = sort(column, OrderEnum.ASC);
        if (Objects.nonNull(column) && columns.length > 0) {
            for (String field : columns) {
                wrapper = sort(field, OrderEnum.ASC);
            }
        }
        return wrapper;
    }

    /**
     * 排序
     *
     * @param column
     * @param order
     * @return
     */
    default Wrapper sort(String column, OrderEnum order) {
        return addLimit(new Arg(QueryEnum.SORT, column, order, null));
    }

    /**
     * 添加限制条件
     *
     * @param arg
     * @return
     */
    Wrapper addLimit(Arg arg);

}
